#!/bin/bash

# ip ip:port ip:port:svc, e.g.  10.10.10.73:2222:ssh
_parse() {
    local t=$2
    IFS=":" read ip port svc <<< $1
    if [ "$t" == "ip" ]; then
        echo "$ip"
    elif [ "$t" == "port" ]; then
        echo "$port"
    elif [ "$t" == "svc" ]; then
        echo "$svc"
    else
        echo "$ip $port $svc"
    fi
}

connect_to() {
    local ip=
    local port=
    local ns=$2 # network namespace
    local ip_cmd=

    ip=$(_parse $1 ip)
    port=$(_parse $1 port)
 
    [ -z "$port" ] && port=22 # default
    [ -n "$ns" ] && ip_cmd="ip netns exec $ns"
    LANG=en $ip_cmd curl -v -s -m 5 $ip:$port 2>&1|grep "^* Connected to" &>/dev/null
    return $?
}

_guess_open_port() {
    local vm=$1
    local image=
    local distro=
    shift

    image=$(get_instance_image $vm $*)
    distro=$(get_image_os_distro $image $*)
    if [ "${distro:0:3}" == "win" ]; then
        echo "3389" # rdp
    else
        echo "22" #ssh
    fi
}

detect_fip() {
    local connstr=$1
    local vmuuid=$2
    local fip=$(_parse $connstr ip)
    local port=$(_parse $connstr port)
    local project=
    local network_id=
    local portid=
    local device_owner=
    local ns=
    local status=

    shift 2

    if [ -z "$port" ]; then
        port=$(_guess_open_port $vmuuid $*)
        [ -n "$port" ] && connstr="$fip:$port"
    fi

    status=$(get_instance_status $vmuuid $*)
    if [ "$status" != "ACTIVE" ]; then
        echo -e "$fip\t$port\t$status"
        return 1
    fi

    # workaround: add --project based --os-project-name
    local hit=false
    for x in $*; do
        if [ "$x" == "--os-project-name" ]; then
            hit=true
        elif $hit; then
            project=$x
            break
        fi
    done
    portid=$(get_port_id "$project" $fip $*)
    if [ -n "$portid" ]; then # empty if port "owned" by floating ip
        device_owner=$(get_port_device_owner $portid $*)
        if [ "${device_owner:0:7}" == "compute" ]; then # fixed ip
            network_id=$(get_network_id  $portid $*)
            # XXX controller must be network node ?
            ns="qdhcp-$network_id"
        fi
    fi

    local loop=6
    while ((loop>0)); do
        connect_to $connstr $ns
        [ $? -eq 0 ] && { echo -e "$fip\t$port\t$status\tsuccess\t$ns"; return 0; }
        ((loop--))
    done
    echo -e "$fip\t$port\t$status\tfailed"
    return 2
}
